#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

#include "gui_view.h"

int ViewSetLayoutGravity(View *view, int gravity)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    params->layout_gravity = gravity;

    return 0;
}

int ViewGetLaoyoutGravity(View *view)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    return params->layout_gravity;
}

int ViewSetLayoutMargin(View *view, int left, int right, int top, int bottom)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    params->margin_left = left;
    params->margin_right = right;
    params->margin_top = top;
    params->margin_bottom = bottom;

    return 0;
}

int ViewGetLayoutMargin(View *view, int *left, int *right, int *top, int *bottom)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    if (left)
        *left = params->margin_left;
    if (right)
        *right = params->margin_right;
    if (top)
        *top = params->margin_top;
    if (bottom)
        *bottom = params->margin_bottom;

    return 0;
}

int ViewSetLayoutSize(View *view, int layout_w, int layout_h)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    params->layout_w = layout_w;
    params->layout_h = layout_h;

    return 0;
}

int ViewGetLayoutSize(View *view, int *layout_w, int *layout_h)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    if (layout_w)
        *layout_w = params->layout_w;
    if (layout_h)
        *layout_h = params->layout_h;

    return 0;
}

int ViewSetLayoutAvailableSize(View *view, int available_w, int available_h)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    params->available_w = available_w;
    params->available_h = available_h;

    return 0;
}

int ViewGetLayoutAvailableSize(View *view, int *available_w, int *available_h)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    if (available_w)
        *available_w = params->available_w;
    if (available_h)
        *available_h = params->available_h;

    return 0;
}

int ViewSetLayoutPosition(View *view, int layout_x, int layout_y)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    params->layout_x = layout_x;
    params->layout_y = layout_y;

    return 0;
}

int ViewGetLayoutPosition(View *view, int *layout_x, int *layout_y)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    if (layout_x)
        *layout_x = params->layout_x;
    if (layout_y)
        *layout_y = params->layout_y;

    return 0;
}

int ViewSetVisibility(View *view, int visibility)
{
    if (!view)
        return -1;

    view->visibility = visibility;

    return 0;
}

int ViewGetVisibility(View *view)
{
    return view ? view->visibility : 0;
}

int ViewSetOrientation(View *view, int orientation)
{
    if (!view)
        return -1;

    view->orientation = orientation;
    return 0;
}

int ViewGetOrientation(View *view)
{
    return view ? view->orientation : 0;
}

int ViewSetGravity(View *view, int gravity)
{
    if (!view)
        return -1;

    view->gravity = gravity;
    return 0;
}

int ViewGetGravity(View *view)
{
    return view ? view->gravity : 0;
}

int ViewSetPadding(View *view, int left, int right, int top, int bottom)
{
    if (!view)
        return -1;

    view->padding_left = left;
    view->padding_right = right;
    view->padding_top = top;
    view->padding_bottom = bottom;

    return 0;
}

int ViewGetPadding(View *view, int *left, int *right, int *top, int *bottom)
{
    if (!view)
        return -1;

    if (left)
        *left = view->padding_left;
    if (right)
        *right = view->padding_right;
    if (top)
        *top = view->padding_top;
    if (bottom)
        *bottom = view->padding_bottom;

    return 0;
}

int ViewSetAutoFree(View *view, int auto_free)
{
    if (!view)
        return -1;

    view->dont_free = !auto_free;
    return 0;
}

int ViewIsAutoFree(View *view)
{
    return view ? !view->dont_free : 0;
}

int ViewSetFocus(View *view, int focused)
{
    if (!view)
        return -1;

    if (view->is_focused != focused)
    {
        view->is_focused = focused;
        if (view->onFocusChange)
            return view->onFocusChange(view, focused);
    }

    return 0;
}

int ViewIsFocused(View *view)
{
    return view ? !view->is_focused : 0;
}

int ViewSetBgColor(View *view, uint32_t color)
{
    if (!view)
        return -1;

    view->bg_color = color;
    return 0;
}

uint32_t ViewGetBgColor(View *view)
{
    return view ? view->bg_color : 0;
}

int ViewSetUserData(View *view, void *data)
{
    if (!view)
        return -1;

    view->userdata = data;
    return 0;
}

void *ViewGetUserData(View *view)
{
    return view ? view->userdata : NULL;
}

int ViewGetMeasuredSize(View *view, int *measured_w, int *measured_h)
{
    if (!view)
        return -1;

    if (measured_w)
        *measured_w = view->measured_w;
    if (measured_h)
        *measured_h = view->measured_h;

    return 0;
}

int ViewGetWrapSize(View *view, int *wrap_w, int *wrap_h)
{
    if (!view)
        return -1;

    if (wrap_w)
        *wrap_w = view->wrap_w;
    if (wrap_h)
        *wrap_h = view->wrap_h;

    return 0;
}

int ViewGetOccupySize(View *view, int *occupy_w, int *occupy_h)
{
    if (!view)
        return -1;

    LayoutParams *params = &view->params;
    // occupy包括margin，而measured不包括，occupy = measured + margin;
    if (occupy_w)
    {
        int w = view->measured_w + params->margin_left + params->margin_right;
        if (w > params->available_w) // 处理下大于可用大小的情况
            *occupy_w = params->available_w;
        else
            *occupy_w = w;
    }
    if (occupy_h)
    {
        int h = view->measured_h + params->margin_top + params->margin_bottom;
        if (h > params->available_h)
            *occupy_h = params->available_h;
        else
            *occupy_h = h;
    }

    return 0;
}

int ViewGetMeasuredContentSize(View *view, int *measured_content_w, int *measured_content_h)
{
    if (!view)
        return -1;

    // measured_content不包括padding，而measured包括，measured_content = measured - padding;
    if (measured_content_w)
    {
        int w = view->measured_w - view->padding_left - view->padding_right;
        if (w < 0) // 处理下小于0的情况
            *measured_content_w = 0;
        else
            *measured_content_w = w;
    }
    if (measured_content_h)
    {
        int h = view->measured_h - view->padding_top - view->padding_bottom;
        if (h < 0)
            *measured_content_h = 0;
        else
            *measured_content_h = h;
    }

    return 0;
}

int ViewGetWrapContentSize(View *view, int *wrap_content_w, int *wrap_content_h)
{
    if (!view)
        return -1;

    // wrap_content不包括padding，而wrap包括，wrap_content = wrap - padding;
    if (wrap_content_w)
    {
        int w = view->wrap_w - view->padding_left - view->padding_right;
        if (w < 0)
            *wrap_content_w = 0;
        else
            *wrap_content_w = w;
    }
    if (wrap_content_h)
    {
        int h = view->wrap_h - view->padding_top - view->padding_bottom;
        if (h < 0)
            *wrap_content_h = 0;
        else
            *wrap_content_h = h;
    }

    return 0;
}

int ViewMeasure(View *view)
{
    if (view && view->onMeasure)
        return view->onMeasure(view);

    return -1;
}

int ViewDraw(View *view)
{
    if (view && view->onDraw)
        return view->onDraw(view);

    return -1;
}

int ViewFinish(View *view)
{
    if (view && view->onFinish)
        view->onFinish(view);

    return -1;
}
